/*
 * Author: Sinclair Ross
 * Additional Functionality implemented by:: Andrew Gillies, Neil Wicker
 * Description: Run the game loop, select characters and set the Tiles in this class. 
 * 
 * Major function authors: 	Initial framework & getNextCharacter() - Sinclair Ross
 * 							detectedTouch(float x, float y) - Neil Wicker
 * 							getRandomCharacters(Context context) - Andrew Gillies
 * 				
 */

package com.forbiddendesert.logic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import android.content.Context;
import android.util.Log;

import com.forbiddendesert.characters.Archaeologist;
import com.forbiddendesert.characters.Character;
import com.forbiddendesert.characters.Climber;
import com.forbiddendesert.characters.Explorer;
import com.forbiddendesert.characters.Meteorologist;
import com.forbiddendesert.characters.Navigator;
import com.forbiddendesert.characters.WaterCarrier;

import com.forbiddendesert.master.RendererPacket;
import com.forbiddendesert.tiles.Tile;

public class GameLogic 
{
	private Board mBoard;
	private Storm mStormSystem;
	private Character mActiveCharacter;
		
	private Vector<Character> mCharacters;
	private Vector<Tile> mTiles;
	private Deque<Character> mCharacterQueue;
	
	private int x = 10;
	private int y = 10;
	
	public GameLogic(RendererPacket packet, Context context)
	{
		mBoard = new Board(context);
		mStormSystem = new Storm(); 
		
		// Initialise player array with capacity of 3
		mCharacters = new Vector<Character>(3);
		// Set the 3 randomly chosen characters.
		packet.SetCharacters(getRandomCharacters(context));
		// Set initial character
		mActiveCharacter = getNextCharacter();
		// Set Tiles
		mTiles = mBoard.getTiles();
		packet.SetTile(mTiles);
	} 
	
	public void Update(Long DeltaTime)
	{
		// Get the next character
		mActiveCharacter = getNextCharacter();
		
		// Output the currently active character
		Log.i("DEBUG GameThread", "Character: " + getNextCharacter() + " is running");
		
		// Process player moves while the player still has remaining moves
		while(mActiveCharacter.getRemainingTurns() > 0)
		{
			//TODO: Determine moves
		}
	}
	
	public void detectedTouch(float x, float y)
	{
		/* Determine the coordinate of the touch.
		 * The X and Y coordinate if calculated by dividing the touch location by the the size of the tile*/
		int row = (int) (y / 100);
		int column = (int) (x / 100);
		
		/* Get the number of tile in the vector
		 * Calulated by the current column plus the number of row multiplied by the current row */
		int element = (column) + (mBoard.getNumRows() * row);
			
		// Deal with the special case of the top row being selected, simply set the element to the column
		if (row == 0)
		{
			element = column;
		}

		// Log touch details
		Log.i("DEBUG GameThread", "Touch Detected");
		Log.i("DEBUG GameThread", "Touched element " + element + " at " + row + ", " + column);
	}
	 
	private Vector<Character> getRandomCharacters(Context context)
	{
	 	/* Create an ArrayList with the specified set of values before shuffling the list. 
		 * Once the list is shuffled you can create an array based off of the first 
		 * three elements in the shuffled list. */
		
		// Create ArrayList
		List<Integer> list = new ArrayList<Integer>();
	    for(int i = 0; i < 6; i++) 
	    {
		   list.add(i);
	    } 
	    
	    // Shuffle list        
	    Collections.shuffle(list);
	    // Create array based off the first 3 elements in the shuffled list	  
	    Integer[] randomArray = list.subList(0, 3).toArray(new Integer[3]);   

	    for(Integer num:randomArray)
	    {	          
	    	/* Assign each character sub-class to a number. 
	    	 * Check these numbers against the random number array.
	    	 * Add character to mCharacters list.
	    	 * Return vector of chosen characters. */
	    	
			switch(num)
			{
				case 0 :
					mCharacters.add(new Archaeologist(context));
					break;
				case 1 :
					mCharacters.add(new Explorer(context));
					break;
				case 2 :
					mCharacters.add(new Climber(context));
					break;
				case 3 :
					mCharacters.add(new Meteorologist(context));
					break;
				case 4 :
					mCharacters.add(new Navigator(context));
					break;
				case 5 :
					mCharacters.add(new WaterCarrier(context));
					break;
					
					default: 
					Log.i("DEBUG GameThread", "NO MORE CHARACTERS FOUND");
			};
			 
	    }
	    
		// Return all the selected characters
		return mCharacters;
	}
	
	
	private Character getNextCharacter()
	{
	
		// Create a new character, intialising to NULL
		Character next = null;
		
		// Create an iterator to look through all characters
		Iterator<Character> players = mCharacters.iterator();
		
		// As long as there is another character
		if(players.hasNext())
		{
			// Assign this character to play next
		    next = players.next();
		}
		else
		{
			// Return first player
		}
		
		// Return next character
		return next;
	}
	
	
	
}
